<?php

namespace Dongasai\WkProtoPhp\Enums;

/**
 * 原因码枚举
 * 使用PHP 8枚举语法
 */
enum ReasonCode: int
{
    case UNKNOWN = 0;                    // 未知错误
    case SUCCESS = 1;                    // 成功
    case AUTH_FAIL = 2;                   // 认证失败
    case SUBSCRIBER_NOT_EXIST = 3;        // 订阅者在频道内不存在
    case IN_BLACKLIST = 4;               // 在黑名单列表里
    case CHANNEL_NOT_EXIST = 5;           // 频道不存在
    case USER_NOT_ON_NODE = 6;           // 用户没在节点上
    case SENDER_OFFLINE = 7;             // 发送者离线了，这条消息将发不成功
    case MSG_KEY_ERROR = 8;              // 消息key错误 说明消息不合法
    case PAYLOAD_DECODE_ERROR = 9;       // payload解码失败
    case FORWARD_SEND_PACKET_ERROR = 10; // 转发发送包失败
    case NOT_ALLOW_SEND = 11;            // 不允许发送消息
    case CONNECT_KICK = 12;              // 连接被踢
    case NOT_IN_WHITELIST = 13;          // 没在白名单内
    case QUERY_TOKEN_ERROR = 14;         // 查询用户token错误
    case SYSTEM_ERROR = 15;               // 系统错误
    case CHANNEL_ID_ERROR = 16;          // 错误的频道ID
    case NODE_MATCH_ERROR = 17;          // 节点匹配错误
    case NODE_NOT_MATCH = 18;            // 节点不匹配
    case BAN = 19;                       // 频道被封禁
    case NOT_SUPPORT_HEADER = 20;        // 不支持的header
    case CLIENT_KEY_IS_EMPTY = 21;       // clientKey 是空的
    case RATE_LIMIT = 22;                // 速率限制
    case NOT_SUPPORT_CHANNEL_TYPE = 23;  // 不支持的频道类型
    case DISBAND = 24;                   // 频道已解散
    case SEND_BAN = 25;                  // 发送被封禁
    case INVALID_VERSION = 26;           // 无效的版本
    case INVALID_AUTH = 27;               // 无效的认证

    /**
     * 获取原因码的字符串表示
     */
    public function toString(): string
    {
        return match ($this) {
            self::UNKNOWN => 'ReasonUnknown',
            self::SUCCESS => 'ReasonSuccess',
            self::AUTH_FAIL => 'ReasonAuthFail',
            self::SUBSCRIBER_NOT_EXIST => 'ReasonSubscriberNotExist',
            self::NOT_ALLOW_SEND => 'ReasonNotAllowSend',
            self::IN_BLACKLIST => 'ReasonInBlacklist',
            self::CHANNEL_NOT_EXIST => 'ReasonChannelNotExist',
            self::USER_NOT_ON_NODE => 'ReasonUserNotOnNode',
            self::SENDER_OFFLINE => 'ReasonSenderOffline',
            self::MSG_KEY_ERROR => 'ReasonMsgKeyError',
            self::PAYLOAD_DECODE_ERROR => 'ReasonPayloadDecodeError',
            self::FORWARD_SEND_PACKET_ERROR => 'ReasonForwardSendPacketError',
            self::CONNECT_KICK => 'ReasonConnectKick',
            self::NOT_IN_WHITELIST => 'ReasonNotInWhitelist',
            self::QUERY_TOKEN_ERROR => 'ReasonQueryTokenError',
            self::SYSTEM_ERROR => 'ReasonSystemError',
            self::CHANNEL_ID_ERROR => 'ReasonChannelIDError',
            self::CLIENT_KEY_IS_EMPTY => 'ReasonClientKeyIsEmpty',
            self::RATE_LIMIT => 'ReasonRateLimit',
            self::DISBAND => 'ReasonDisband',
            self::NOT_SUPPORT_HEADER => 'ReasonNotSupportHeader',
            self::NODE_MATCH_ERROR => 'ReasonNodeMatchError',
            self::NODE_NOT_MATCH => 'ReasonNodeNotMatch',
            self::BAN => 'ReasonBan',
            self::NOT_SUPPORT_CHANNEL_TYPE => 'ReasonNotSupportChannelType',
            self::SEND_BAN => 'ReasonSendBan',
            self::INVALID_VERSION => 'ReasonInvalidVersion',
            self::INVALID_AUTH => 'ReasonInvalidAuth',
        };
    }

    /**
     * 转换为字节
     */
    public function toByte(): int
    {
        return $this->value & 0xFF;
    }

    /**
     * 从值创建枚举实例
     */
    public static function fromValue(int $value): self
    {
        return self::from($value);
    }

    /**
     * 检查是否为成功状态
     */
    public function isSuccess(): bool
    {
        return $this === self::SUCCESS;
    }

    /**
     * 检查是否为错误状态
     */
    public function isError(): bool
    {
        return $this !== self::SUCCESS;
    }

    /**
     * 获取错误分类
     */
    public function getCategory(): string
    {
        return match ($this) {
            self::SUCCESS => 'success',
            self::UNKNOWN, self::SYSTEM_ERROR => 'system',
            self::AUTH_FAIL, self::NOT_IN_WHITELIST, self::QUERY_TOKEN_ERROR, 
            self::CLIENT_KEY_IS_EMPTY => 'authentication',
            self::CHANNEL_NOT_EXIST, self::CHANNEL_ID_ERROR, self::SUBSCRIBER_NOT_EXIST,
            self::USER_NOT_ON_NODE, self::DISBAND => 'channel',
            self::SENDER_OFFLINE, self::MSG_KEY_ERROR, self::PAYLOAD_DECODE_ERROR,
            self::FORWARD_SEND_PACKET_ERROR, self::NOT_ALLOW_SEND => 'message',
            self::CONNECT_KICK, self::RATE_LIMIT, self::SEND_BAN => 'connection',
            self::IN_BLACKLIST, self::BAN => 'permission',
            self::NODE_MATCH_ERROR, self::NODE_NOT_MATCH => 'routing',
            self::NOT_SUPPORT_HEADER, self::NOT_SUPPORT_CHANNEL_TYPE => 'protocol',
        };
    }

    /**
     * 向后兼容的toString方法
     */
    public static function toStringFromValue(int $reasonCode): string
    {
        try {
            return self::from($reasonCode)->toString();
        } catch (\ValueError $e) {
            return sprintf('ReasonUnknown[%d]', $reasonCode);
        }
    }

    /**
     * 向后兼容的toByte方法
     */
    public static function toByteFromValue(int $reasonCode): int
    {
        return $reasonCode & 0xFF;
    }
}